//
//  AIChatViewModel.swift
//  TestIos
//
//  Created by 李亚东 on 2025/11/4.
//  Copyright © 2025 Liyadong. All rights reserved.
//

import UIKit
import Foundation

// MARK: - ViewModel 更新通知协议
protocol AIChatViewModelDelegate: AnyObject {
    /// 消息列表更新（新增消息）
    func viewModelDidAddMessage(_ viewModel: AIChatViewModel, at indexPath: IndexPath)
    
    /// 需要更新指定 cell 的内容（用于打字机效果）
    func viewModel(_ viewModel: AIChatViewModel, shouldUpdateCellAt indexPath: IndexPath, with content: String, shouldUpdateHeight: Bool)
    
    /// 需要滚动到底部
    func viewModel(_ viewModel: AIChatViewModel, shouldScrollToBottom animated: Bool)
    
    /// 打字机动画状态变化（开始/结束）
    func viewModel(_ viewModel: AIChatViewModel, typingAnimationDidChange isAnimating: Bool)
}

class AIChatViewModel {
    
    // MARK: - Properties
    weak var delegate: AIChatViewModelDelegate?
    
    private(set) var messages: [ChatMessage] = []
    
    // 打字机动画相关
    private var typingTimer: Timer?
    private var currentTypingIndex: Int = 0
    private var currentTypingMessage: ChatMessage?
    private var currentTypingIndexPath: IndexPath?
    private var lastUpdateTime: TimeInterval = 0
    private let updateInterval: TimeInterval = 0.06  // 每60ms更新一次UI，平衡流畅度和抖动
    
    // 滚动状态管理
    private var isUserScrolling: Bool = false
    private var shouldAutoScroll: Bool = true
    
    // 消息生成状态管理
    private(set) var isGeneratingMessage: Bool = false  // 是否正在生成AI消息
    
    // MARK: - Initialization
    init() {
        addWelcomeMessage()
    }
    
    deinit {
        typingTimer?.invalidate()
    }
    
    // MARK: - Public Methods
    
    /// 添加欢迎消息
    func addWelcomeMessage() {
        let welcomeMessage = ChatMessage(
            type: .assistant,
            content: "你好！我是AI助手，有什么可以帮助你的吗？"
        )
        messages.append(welcomeMessage)
        let indexPath = IndexPath(row: messages.count - 1, section: 0)
        delegate?.viewModelDidAddMessage(self, at: indexPath)
    }
    
    /// 发送用户消息
    func sendMessage(_ text: String) {
        // 如果正在生成消息，不允许发送新消息
        guard !isGeneratingMessage else {
            return
        }
        
        let userMessage = ChatMessage(type: .user, content: text)
        messages.append(userMessage)
        let indexPath = IndexPath(row: messages.count - 1, section: 0)
        delegate?.viewModelDidAddMessage(self, at: indexPath)
        
        // 重置自动滚动状态
        shouldAutoScroll = true
        
        // 模拟AI回复
        simulateAIResponse(to: text)
    }
    
    /// 更新滚动状态
    func updateScrollState(isScrolling: Bool, isAtBottom: Bool) {
        isUserScrolling = isScrolling
        
        if isScrolling && !isAtBottom {
            shouldAutoScroll = false
        } else if !isScrolling && isAtBottom {
            shouldAutoScroll = true
        }
    }
    
    /// 检查是否应该自动滚动
    func shouldAutoScrollToBottom(isAtBottom: Bool) -> Bool {
        return shouldAutoScroll && isAtBottom && !isUserScrolling
    }
    
    /// 停止打字机动画
    func stopTypingAnimation() {
        typingTimer?.invalidate()
        typingTimer = nil
        currentTypingMessage = nil
        currentTypingIndex = 0
        currentTypingIndexPath = nil
        lastUpdateTime = 0
        
        // 更新生成状态
        isGeneratingMessage = false
        
        // 通知动画已停止
        delegate?.viewModel(self, typingAnimationDidChange: false)
    }
    
    // MARK: - Private Methods
    
    /// 模拟AI回复
    private func simulateAIResponse(to userMessage: String) {
        // 标记开始生成消息
        isGeneratingMessage = true
        
        // 立即添加一个 loading 状态的 AI 消息
        let loadingMessage = ChatMessage(type: .assistant, content: "正在思考...", isLoading: true)
        self.messages.append(loadingMessage)
        
        // 通知添加新行
        let indexPath = IndexPath(row: self.messages.count - 1, section: 0)
        self.delegate?.viewModelDidAddMessage(self, at: indexPath)
        
        // 延迟1秒后生成AI回复并替换loading消息
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
            guard let self = self else { return }
            
            // 生成模拟回复
            let aiResponse = self.generateAIResponse(for: userMessage)
            
            // 更新消息内容，取消loading状态
            var updatedMessage = self.messages[indexPath.row]
            updatedMessage.content = aiResponse
            updatedMessage.isLoading = false
            self.messages[indexPath.row] = updatedMessage
            
            // 通知更新消息内容
            self.delegate?.viewModel(self, shouldUpdateCellAt: indexPath, with: aiResponse, shouldUpdateHeight: true)
            
            // 开始打字机动画
            self.startTypingAnimation(for: updatedMessage, at: indexPath)
        }
    }
    
    /// 生成AI回复
    private func generateAIResponse(for userMessage: String) -> String {
        let tempMsg: String = "拓展之美：在代码与生活的边界绽放在编程的世界里，Swift 扩展（Extension）宛如一把神奇的钥匙，为既有的类型开启了无限可能的大门。它如同一位技艺精湛的工匠，在原有的框架之上雕琢出精致的细节，让代码焕发出全新的活力。而在生活的舞台上，我们也常常需要这种扩展的精神，去突破局限，探索未知，书写属于自己的精彩篇章。代码世界的扩展魔法Swift 扩展的魅力，首先体现在它对系统类型的强大赋能上。以 UIColor 为例，在未扩展之前，它只是系统提供的一系列预设颜色。但通过扩展，我们可以为其注入个性化的色彩定义。就像为单调的画布添上了绚丽的颜料，我们可以轻松定义主色调、辅助色、背景色和文字色等。这种扩展不仅让代码更加语义化，提高了可读性，还方便了团队之间的协作与维护。在一个大型项目中，统一的颜色定义通过扩展得以实现，确保了整个应用界面风格的一致性，仿佛为应用穿上了一件精心设计的时尚外衣。扩展还能为系统类型添加实用的功能。例如，为 String 类型扩展一个判断是否为有效邮箱的方法。通过正则表达式，我们可以快速准确地验证用户输入的邮箱格式是否正确。这一小小的扩展，却在实际开发中发挥着巨大的作用。它避免了重复编写验证代码的繁琐，提高了开发效率，同时也减少了因人为疏忽而导致的错误。就像为一把普通的钥匙添加了特殊的齿纹，让它能够打开更多重要的门锁。此外，扩展还可以为自定义类型增添新的行为。假设我们有一个 User 结构体，包含用户的姓名和年龄信息。通过扩展使其符合 CustomStringConvertible 协议，我们可以自定义 User 的字符串描述方式。当调用 print(user) 时，不再是简单的输出内存地址，而是以友好的格式显示用户的详细信息。这种扩展让自定义类型更加灵活，能够更好地与外界交互，就像为一个人赋予了独特的个性和魅力，使其在社交场合中更加引人注目。生活领域的扩展精神代码世界的扩展如此神奇，而在生活中，扩展精神同样不可或缺。我们每个人都像是被设定好初始属性的对象，拥有一定的技能、知识和经验。然而，如果我们满足于现状，不进行自我扩展，就如同被困在狭小的牢笼中，无法领略外面广阔世界的精彩。学习是生活扩展的重要途径。就像代码通过扩展获得新功能一样，我们通过学习新的知识和技能，不断丰富自己的内涵。学习一门新的语言，我们可以打开与不同文化交流的大门；掌握一项新的技术，我们可以在职场中脱颖而出；培养一种新的兴趣爱好，我们可以让生活变得更加丰富多彩。每一次学习都是一次自我扩展的过程，它让我们的视野更加开阔，思维更加敏捷，能力更加强大。        社交也是生活扩展的关键环节。与不同背景的人交往，就像为代码引入外部库一样，能够为我们带来新的观点和想法。通过与他人的交流和合作，我们可以了解到不同的生活方式、价值观和解决问题的方法。这些新鲜的元素能够激发我们的创造力，让我们在面对困难时找到更多的解决方案。同时，良好的社交关系还能为我们提供情感支持，帮助我们度过人生的低谷，就像代码中的依赖关系，相互支持，共同成长。旅行则是生活扩展的一种独特方式。离开熟悉的环境，踏上陌生的土地，我们仿佛进入了一个全新的代码世界。不同的地理风貌、人文景观和风俗习惯，让我们感受到世界的多样性和无限可能。在旅行中，我们学会了适应变化，解决问题，培养了独立和勇敢的品质。每一次旅行都是一次自我发现和自我扩展的旅程，它让我们更加了解自己，也更加热爱这个世界。拓展之美，无处不在无论是代码世界的扩展，还是生活领域的拓展，都展现了一种积极向上、勇于探索的精神。在代码中，扩展让我们能够以更加高效、优雅的方式解决问题，创造出更加优秀的应用；在生活中，拓展让我们不断突破自我，实现人生的价值。"
        
        // 简单的模拟回复逻辑（实际应用中应该调用真实的AI API）
        let lowerMessage = userMessage.lowercased()
        
        if lowerMessage.contains("你好") || lowerMessage.contains("hello") {
            return "你好！很高兴见到你。有什么我可以帮助你的吗？"
        } else if lowerMessage.contains("时间") || lowerMessage.contains("现在") {
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
            return "当前时间是：\(formatter.string(from: Date()))"
        } else if lowerMessage.contains("天气") {
            return "抱歉，我目前无法获取实时天气信息。建议你查看天气应用或网站获取准确的天气预报。"
        } else if lowerMessage.contains("帮助") || lowerMessage.contains("help") {
            return "我可以帮你回答各种问题，进行对话交流。你可以问我任何问题，我会尽力帮助你！"
        } else if lowerMessage.contains("再见") || lowerMessage.contains("bye") {
            return "再见！很高兴和你聊天，期待下次再见！"
        } else {
            return "我理解你说的是：" + userMessage + "。这是一个很有趣的话题！如果你有更多问题，随时可以问我。" + tempMsg
        }
    }
    
    /// 开始打字机动画
    private func startTypingAnimation(for message: ChatMessage, at indexPath: IndexPath) {
        currentTypingMessage = message
        currentTypingIndex = 0
        currentTypingIndexPath = indexPath
        
        let fullText = message.content
        let totalCharacters = fullText.count
        
        // 清除现有定时器
        typingTimer?.invalidate()
        
        // 通知动画开始
        delegate?.viewModel(self, typingAnimationDidChange: true)
        
        // 每次显示2-5个字符，随机变化以模拟真实流式传输
        let minCharsPerBatch = 2
        let maxCharsPerBatch = 5
        
        // 创建定时器，分批显示文字（模拟流式传输）
        typingTimer = Timer.scheduledTimer(withTimeInterval: 0.03, repeats: true) { [weak self] timer in
            guard let self = self,
                  let indexPath = self.currentTypingIndexPath else {
                timer.invalidate()
                return
            }
            
            if self.currentTypingIndex < totalCharacters {
                // 随机决定这次显示几个字符（2-5个），让效果更自然
                let charsToShow = min(
                    Int.random(in: minCharsPerBatch...maxCharsPerBatch),
                    totalCharacters - self.currentTypingIndex
                )
                
                // 更新显示的字符数
                self.currentTypingIndex += charsToShow
                
                // 确保不超过总长度
                let endIndex = min(self.currentTypingIndex, totalCharacters)
                let textIndex = fullText.index(fullText.startIndex, offsetBy: endIndex)
                let partialText = String(fullText[..<textIndex])
                
                // 更新消息内容
                var updatedMessage = self.messages[indexPath.row]
                updatedMessage.content = partialText
                self.messages[indexPath.row] = updatedMessage
                
                // 节流更新：只在指定时间间隔后更新UI
                let currentTime = CACurrentMediaTime()
                let shouldUpdateHeight = currentTime - self.lastUpdateTime >= self.updateInterval
                
                if shouldUpdateHeight {
                    self.lastUpdateTime = currentTime
                }
                
                // 通知更新 cell 内容和高度
                self.delegate?.viewModel(self, shouldUpdateCellAt: indexPath, with: partialText, shouldUpdateHeight: shouldUpdateHeight)
                
                // 如果需要更新高度且允许自动滚动，则滚动到底部
                if shouldUpdateHeight && self.shouldAutoScroll {
                    self.delegate?.viewModel(self, shouldScrollToBottom: false)
                }
                
            } else {
                // 动画完成，确保显示完整内容
                var finalMessage = self.messages[indexPath.row]
                finalMessage.content = message.content
                self.messages[indexPath.row] = finalMessage
                
                // 通知最终更新
                self.delegate?.viewModel(self, shouldUpdateCellAt: indexPath, with: message.content, shouldUpdateHeight: true)
                
                // 最终检查是否需要滚动
                if self.shouldAutoScroll {
                    self.delegate?.viewModel(self, shouldScrollToBottom: true)
                }
                
                // 清理状态
                timer.invalidate()
                self.typingTimer = nil
                self.currentTypingMessage = nil
                self.currentTypingIndex = 0
                self.currentTypingIndexPath = nil
                self.lastUpdateTime = 0
                
                // 更新生成状态
                self.isGeneratingMessage = false
                
                // 通知动画结束
                self.delegate?.viewModel(self, typingAnimationDidChange: false)
            }
        }
    }
}

